package app

import (
	"chatgpt/helper"
	"chatgpt/helper/code"
	"chatgpt/logq"
	"chatgpt/model/app"
	"chatgpt/services/datasrv"
	"chatgpt/services/datasrv/sqlhelper"
	"context"
	"time"
)

type PriceSrv struct {
}

// 为商品，批量配套价格
func (self *PriceSrv) AttachMuch(procs []*app.Product, prices []*app.Price) {
	if procs == nil || prices == nil {
		return
	}
	for _, p := range procs {
		self.AttachOne(p, prices)
	}
}

func (self *PriceSrv) AttachOne(proc *app.Product, prices []*app.Price) {
	if prices == nil || len(prices) == 0 || proc == nil {
		return
	}
	for _, p := range prices {
		if uint(p.ProcID) != proc.ProcID {
			continue
		}
		if p.Origin == helper.PRICE_ORIGIN {
			proc.PriceOrigin = p.Price
			if proc.PriceDiscount == 0 {
				proc.PriceDiscount = p.Price
			}
			continue
		}
		expire := true
		if time.Unix(int64(p.ExpiredAt), 0).Sub(time.Now()) > 0 || p.ExpiredAt == -1 {
			expire = false
		}
		if p.Origin != helper.PRICE_ORIGIN && !expire {
			proc.PriceDiscount = p.Price
		}
	}
}

func (self *PriceSrv) GetList(offset, limit int) []*app.Price {
	datas := self.GetListDB(&sqlhelper.Where{
		Order:  "updated_at DESC",
		Offset: offset,
		Limit:  limit,
	})
	if datas == nil {
		return datas
	}
	return datas
}

func (self *PriceSrv) GetListByProcID(id int) []*app.Price {
	now := time.Now()
	datas := self.GetListDB(&sqlhelper.Where{
		Order: "updated_at DESC",
		Limit: 1000,
		Conds: []*sqlhelper.CondItem{
			sqlhelper.WhereCond("ProcID", id),
			sqlhelper.WhereCond("DeletedAt", 0),
			sqlhelper.WhereCond("ExpiredAt", now.Unix(), ">="),
			sqlhelper.WhereCond("StartAt", now.Unix(), "<="),
			sqlhelper.WhereCond("ExpiredAt", -1),
		},
		Formula: "{1} AND {2} AND (({3} AND {4}) or {5})",
	})
	if datas == nil {
		return datas
	}
	return datas
}

func (self *PriceSrv) GetListWithIds(ids []int, limit int) []*app.Price {
	now := time.Now()
	if limit == 0 {
		limit = 1000
	}
	datas := self.GetListDB(&sqlhelper.Where{
		Order: "updated_at DESC",
		Limit: limit,
		Conds: []*sqlhelper.CondItem{
			sqlhelper.WhereCond("ProcID", ids, "IN"),
			sqlhelper.WhereCond("DeletedAt", 0),
			sqlhelper.WhereCond("ExpiredAt", now.Unix(), ">="),
			sqlhelper.WhereCond("StartAt", now.Unix(), "<="),
			sqlhelper.WhereCond("ExpiredAt", -1, "="),
		},
		Formula: "{1} AND {2} AND (({3} AND {4}) or {5})",
	})
	if datas == nil {
		return datas
	}
	return datas
}

func (self *PriceSrv) GetListDB(where *sqlhelper.Where) []*app.Price {
	res := sqlhelper.ResWhere{}
	mc := datasrv.AppDB.PriceSelect(context.Background(), &sqlhelper.ReqWhere{
		Where: where,
	}, &res)
	if res.MsgCode != code.SUCCESS {
		logq.InfoF("PriceSrv.GET code:%v", mc)
		return nil
	}
	data_arr, ok := res.Data.([]any)
	if !ok {
		return nil
	}

	rtn := []*app.Price{}
	for _, v := range data_arr {
		m, ok := v.(map[string]any)
		if !ok {
			continue
		}
		tmp := &app.Price{}
		tmp.ConvFromMap(m)
		rtn = append(rtn, tmp)
	}
	return rtn
}

func (self *PriceSrv) Save(p *app.Price) code.CODENO {
	res := sqlhelper.ResWhere{}
	mc := datasrv.AppDB.PriceSave(context.Background(), &sqlhelper.ReqWhere{
		Object: p.ConvToMap(),
		Where: &sqlhelper.Where{
			Conds: []*sqlhelper.CondItem{sqlhelper.WhereCond("ID", p.ID)},
		},
	}, &res)
	if res.MsgCode != code.SUCCESS {
		logq.InfoF("PriceSrv.SAVE code:%v", mc)
		return res.MsgCode
	}
	return code.SUCCESS
}

func (self *PriceSrv) FirstDB(where *sqlhelper.Where) *app.Price {
	res := sqlhelper.ResWhere{}
	mc := datasrv.AppDB.PriceFirst(context.Background(), &sqlhelper.ReqWhere{
		Where: where,
	}, &res)
	if res.MsgCode != code.SUCCESS {
		logq.InfoF("PriceSrv.First code:%v", mc)
		return nil
	}
	data_arr, ok := res.Data.(map[string]any)
	if !ok {
		return nil
	}
	rtn := &app.Price{}
	rtn.ConvFromMap(data_arr)
	return rtn
}

func (self *PriceSrv) Delete(id int) code.CODENO {
	res := sqlhelper.ResWhere{}
	mc := datasrv.AppDB.PriceDelete(context.Background(), &sqlhelper.ReqWhere{
		Where: &sqlhelper.Where{
			Conds: []*sqlhelper.CondItem{sqlhelper.WhereCond("ID", id)},
		},
	}, &res)
	if res.MsgCode != code.SUCCESS {
		logq.InfoF("PriceSrv.SAVE code:%v", mc)
		return res.MsgCode
	}
	return code.SUCCESS
}
